home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1989 / 09 / king.lst < prev    next >
File List  |  1989-07-27  |  6KB  |  311 lines

  1. _FORCED-BASED SIMULATIONS_
  2. by Todd King
  3.  
  4. [LISTING ONE]
  5.  
  6. /*-------------------------------------
  7.   Basic object classes and method
  8.   definitions for simulation software
  9.   File: simul.hpp
  10.   Todd King
  11. ----------------------------------------*/
  12. #include <stream.hpp>
  13. #include <disp.h>
  14. #include <conio.h>
  15. #include <math.h>
  16. #include <time.h>
  17. #include <math.h>
  18. #include "simconst.h"
  19.  
  20. #define ESC    27
  21. #define MAX_BODY_POOL    100
  22.  
  23. typedef struct VECTOR_2D {
  24.   double x, y;
  25. };
  26.  
  27. class BODY {
  28.   VECTOR_2D world;
  29.   VECTOR_2D velocity;
  30.   double mass;
  31.   double gmass;
  32.   char icon;
  33. public:
  34.   BODY();
  35.   set_mass(double m);
  36.   set_velocity(double x, double y);
  37.   set_position(double x, double y);
  38.   apply_force(VECTOR_2D from, double amount);
  39.   VECTOR_2D position();
  40.   double get_gmass();
  41.   update();
  42.   set_icon(char c);
  43. };
  44.  
  45. /* Distance and time units are converted to screen units and ticks */
  46. BODY::set_mass(double m) { 
  47.   double pow();
  48.  
  49.   mass = m;
  50.   gmass = G * m;
  51. };
  52.  
  53. BODY::set_velocity(double x, double y) {
  54.   velocity.x = x;
  55.   velocity.y = y;
  56. };
  57.  
  58. BODY::set_position(double x, double y) {
  59.   world.x = x;
  60.   world.y = y;
  61. };
  62.  
  63. BODY::apply_force(VECTOR_2D from, double gmass) {
  64.   VECTOR_2D d;
  65.   double rs;
  66.   double v;
  67.   double r;
  68.  
  69.   d.x = world.x - from.x;
  70.   d.y = world.y - from.y;
  71.  
  72.   rs =  (d.x * d.x) + (d.y * d.y);
  73.   if(rs != 0.0) {    // there's a seperation
  74.     r = sqrt(rs);
  75.     v = (gmass / rs) * SECS_PER_TIC;
  76.     velocity.x += v * d.x / r;
  77.     velocity.y += v * d.y / r;
  78.   }
  79. };
  80.  
  81. BODY::BODY() {
  82.   world.x = 0;
  83.   world.y = 0;
  84.   velocity.x = 0;
  85.   velocity.y = 0;
  86.   icon = '*';
  87. };
  88.  
  89. VECTOR_2D BODY::position() {
  90.   VECTOR_2D vec;
  91.  
  92.   vec.x = world.x;
  93.   vec.y = world.y;
  94.   return(vec);
  95. };
  96.  
  97. double BODY::get_gmass() {
  98.   return(gmass);
  99. }
  100.  
  101. BODY::set_icon(char c) { icon = c; }
  102.  
  103. class UNIVERSE {
  104.   unsigned int body_cnt;
  105.   BODY *body_pool[MAX_BODY_POOL];
  106. public:
  107.   UNIVERSE();
  108.   service(BODY *bptr);
  109.   big_bang();
  110. };
  111.  
  112. UNIVERSE::UNIVERSE() {
  113.   body_cnt = 0;
  114. };
  115.  
  116. UNIVERSE::service(BODY *bptr) {
  117.   if(body_cnt >= MAX_BODY_POOL) return(0);
  118.   body_pool[body_cnt] = bptr;
  119.   body_cnt++;
  120. };
  121.  
  122. UNIVERSE::big_bang() {
  123.   int i, j;
  124.  
  125.   init_screen();
  126.  
  127.   print_message(" Press ESC to stop.");
  128.   for(;;) {
  129.     print_tick();
  130.     if(kbhit()) {
  131.       switch(getch())
  132.       {
  133.          case ESC:
  134.             return(0);
  135.       }
  136.     }
  137.     sleep(0.1); 
  138.  
  139. /* Let each body influence all others */
  140.     for(i = 0; i < body_cnt; i++) {
  141.       for(j = 0; j < body_cnt; j++) {
  142.         if(j == i) continue;    // don't apply force to self
  143.         body_pool[i]->apply_force(body_pool[j]->position(), 
  144.           body_pool[j]->get_gmass());
  145.       }
  146.     }
  147.  
  148. /* Display all bodies */
  149.     for(i = 0; i < body_cnt; i++) {
  150.       body_pool[i]->update();
  151.     }
  152.  
  153.   }
  154.   deinit_screen();
  155. };
  156.  
  157. sleep(double seconds) {
  158.   time_t ltime1, ltime2;
  159.  
  160.   time(<ime1);
  161.   time(<ime2);
  162.   while(difftime(ltime1, ltime2) < seconds) {
  163.     time(<ime2);
  164.   }
  165. }
  166.  
  167.  
  168.  
  169. [LISTING TWO] 
  170.  
  171. /*--------------------------------------------
  172.    Methods which are related to screen I/O.
  173.    File: simulscr.hpp
  174.    Todd King
  175. ----------------------------------------------*/
  176. #include "simconst.h"
  177.  
  178. #define DISPLAY_Y    24
  179. #define DISPLAY_X    80
  180.  
  181. BODY::update() {
  182.    extern VECTOR_2D Extent;
  183.  
  184.    VECTOR_2D screen;
  185.  
  186.   screen.x = DISPLAY_X * (world.x / EXTENT_X);
  187.   screen.y = DISPLAY_Y * (world.y / EXTENT_Y);
  188.   if( (screen.x < DISPLAY_X && screen.x >= 0.0) &&
  189.       (screen.y < DISPLAY_Y && screen.y >= 0.0) ) { 
  190.     disp_move(DISPLAY_Y - (int) screen.y, (int) screen.x);
  191.     disp_printf(" ");
  192.   }
  193.  
  194.   world.x += velocity.x * SECS_PER_TIC;
  195.   world.y += velocity.y * SECS_PER_TIC;
  196.  
  197.   screen.x = DISPLAY_X * (world.x / EXTENT_X);
  198.   screen.y = DISPLAY_Y * (world.y / EXTENT_Y);
  199.   if( (screen.x < DISPLAY_X && screen.x >= 0.0) &&
  200.       (screen.y < DISPLAY_Y && screen.y >= 0.0) ) { 
  201.     disp_move(DISPLAY_Y - (int) screen.y, (int) screen.x);
  202.     disp_printf("%c", icon);
  203.   }
  204.   disp_move(0,0);
  205. };
  206.  
  207. init_screen() {
  208.   disp_open();
  209.   disp_move(0, 0);
  210.   disp_eeop();
  211. }
  212.  
  213. deinit_screen() {
  214.   disp_close();
  215. }
  216.  
  217. print_tick() {
  218.   static unsigned int Tick = 0;
  219.  
  220.   disp_move(0, 0);
  221.   disp_printf("Tick: %u", Tick);
  222.   Tick++;
  223. }
  224.  
  225. print_message(char mesg[]) {
  226.   disp_move(24,0);
  227.   disp_printf(mesg);
  228. }
  229.  
  230.  
  231. [LISTING FOUR]
  232.  
  233. /*------------------------------------------------
  234.    Simulation of what would happen if a planet
  235.    about twice the size of the Moon passed 
  236.    close to the earth within the Moon's orbit.
  237.    Todd King
  238. --------------------------------------------------*/
  239. #include "simul.hpp"
  240. #include "simulscr.hpp"
  241.  
  242. main() {
  243.   BODY earth;
  244.   BODY moon;
  245.   BODY planet_x;
  246.   UNIVERSE universe;
  247.  
  248.   earth.set_mass(5.98e24);
  249.   earth.set_position(5.0e8, 5.0e8);
  250.   earth.set_icon('E');
  251.   moon.set_mass(7.36e22);
  252.   moon.set_position(5.0e8, 8.8e8);
  253.   moon.set_icon('M');
  254.   moon.set_velocity(-1020.0, 0.0);
  255.   planet_x.set_mass(14.8e22);
  256.   planet_x.set_position(1.0, 1.0e4);
  257.   planet_x.set_icon('X');
  258.   planet_x.set_velocity(1800, 2000);
  259.  
  260.   universe.service(&earth);
  261.   universe.service(&moon);
  262.   universe.service(&planet_x);
  263.   universe.big_bang();
  264. }
  265.  
  266.  
  267.  
  268. [LISTING FOUR]
  269.  
  270. /*-----------------------------------------------------
  271.   Various constants which affect the simulation
  272.   system.  Units are in meters, seconds and Kilograms.
  273.   File: simconst.h
  274.   Todd King
  275. -------------------------------------------------------*/
  276. #define G    -6.67e-11    /* Gravitational constant */
  277. #define SECS_PER_TIC    86400    /* One day */
  278. #define EXTENT_X    10e8    /* Width of displayed universe */
  279. #define EXTENT_Y    10e8    /* Hieght of displayed universe */
  280.  
  281.  
  282.  
  283. [EXAMPLE 1]
  284.  
  285. /*-----------------------------------------------
  286.    Simulates the orbital dynamics of the Earth 
  287.    and Moon.
  288.    Todd King
  289. -------------------------------------------------*/
  290. #include "simul.hpp"
  291. #include "simulscr.hpp"
  292.  
  293. main() {
  294.   BODY earth;
  295.   BODY moon;
  296.   UNIVERSE universe;
  297.  
  298.   earth.set_mass(5.98e24);
  299.   earth.set_position(5.0e8, 5.0e8);
  300.   earth.set_icon('E');
  301.   moon.set_mass(7.36e22);
  302.   moon.set_position(5.0e8, 8.8e8);
  303.   moon.set_icon('M');
  304.   moon.set_velocity(-1020.0, 0.0);
  305.  
  306.   universe.service(&earth);
  307.   universe.service(&moon);
  308.   universe.big_bang();
  309. }
  310.  
  311.